#pragma once

#include <iostream>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#define SIZE 1024

//日志等级0~4
#define Info 0
#define Debug 1
#define Warrning 2
#define Error 3
#define Fatal 4

#define Screan 1                   //向显示器打印
#define Onefile 2                  //向一个文件打印
#define Classfile 3                //分类打印

#define logFile "log.txt"


class Log
{
public:
	Log()          
	{
		printMethod = Screan;       //默认向显示器打印
		path="./log/";
	}

	void Enable(int method)         //打印格式
	{
		printMethod = method;
	}

	//日志等级函数，将整数风格转换成字符串风格
	std::string levelToString(int level)
	{
		switch (level)
		{
		case Info:return "Info";
		case Debug:return "Debug";
		case Warrning:return "Warrning";
		case Error:return "Error";
		case Fatal:return "Fatal";
		default:return "None";
		}
	}

	/*
	//传入日志等级和内容
	void logmessage(int level, const char* format, ...)
	{
		//默认部分(时间+等级)
		time_t t = time(nullptr);             //返回值是时间戳
		struct tm* ctime = localtime(&t);
		char leftbuf[SIZE];                 //存放默认部分

		//年份是按1900年开始，月份第0月，将这些信息放入leftbuf数组里，注意转换字符串的函数
		snprintf(leftbuf, sizeof(leftbuf), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(), \
			ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);


		//自定义部分(用户输入的部分)
		va_list s;
		va_start(s, format);
		char rightbuf[SIZE];                //存放自定义部分
		vsnprintf(rightbuf, sizeof(rightbuf), format, s);
		va_end(s);


		//存放日志的所有内容(默认部分+自定义部分)
		char logtxt[SIZE * 2];

		//将日志内容放入logtxt数组里
		snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuf, rightbuf);

		//printf("%s", logtxt);                //将日志内容都打印到显示器
        printLog(level,logtxt);
	}
	*/
    void printLog(int level,const std::string logtxt)
    {
        switch(printMethod)
        {
            case Screan:
                std::cout<<logtxt<<std::endl;
            break;
            case Onefile:
                printOneFile(logFile,logtxt);
            break;
            case Classfile:
                printClassFile(level,logtxt);
            break;
            default:
            break;
        }
    }
    void printOneFile(const std::string& logname,const std::string& logtxt)
    {
		std::string _logname=path+logname;
        int fd=open(_logname.c_str(),O_WRONLY|O_CREAT|O_APPEND,0666);	//log.txt
        if(fd<0) return; 
        write(fd,logtxt.c_str(),logtxt.size());
        close(fd);  
    }
    void printClassFile(int level,const std::string& logtxt)
    {
        std::string filename=logFile;		//默认文件名logFile
		filename+=".";
		filename+=levelToString(level);		//日志后缀，例如：log.txt.Debug/warning
		printOneFile(filename,logtxt);
    }
	~Log()
	{}

	//重载后直接就能调用log了
	void operator()(int level,const cahr *format,...)		
	{
		time_t t = time(nullptr);             //返回值是时间戳
		struct tm* ctime = localtime(&t);
		char leftbuf[SIZE];                 //存放默认部分

		//年份是按1900年开始，月份第0月，将这些信息放入leftbuf数组里，注意转换字符串的函数
		snprintf(leftbuf, sizeof(leftbuf), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(), \
			ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);


		//自定义部分(用户输入的部分)
		va_list s;
		va_start(s, format);
		char rightbuf[SIZE];                //存放自定义部分
		vsnprintf(rightbuf, sizeof(rightbuf), format, s);
		va_end(s);


		//存放日志的所有内容(默认部分+自定义部分)
		char logtxt[SIZE * 2];

		//将日志内容放入logtxt数组里
		snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuf, rightbuf);

		//printf("%s", logtxt);                //将日志内容都打印到显示器
        printLog(level,logtxt);
	}
private:
	int printMethod;		//向显示器或文件打印的格式
	std::string path;		//路径
};


/*可变参数
 int sum(int n,...)
 {
    va_list s;          //char* 
    va_start(s,n);
    
    int sum=0;
    while(n)
    {
        sum+=va_arg(s,int);          //va_list s,type，根据类型提参数
        n--;
    }
    va_end(s);          //s=NULL     
    return sum;
 }
*/
